package com.sgcc.sx.pmos.common.utils;

import android.text.TextUtils;

import java.math.BigDecimal;

public class BigDecimalUtils {

    /**
     * 保留两位小数---------四舍五入
     * 1、ROUND_UP
     * 舍入远离零的舍入模式。
     * 在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。
     * 注意，此舍入模式始终不会减少计算值的大小。
     * 2、ROUND_DOWN
     * 接近零的舍入模式。
     * 在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1，即截短)。
     * 注意，此舍入模式始终不会增加计算值的大小。
     * 3、ROUND_CEILING
     * 接近正无穷大的舍入模式。
     * 如果 BigDecimal 为正，则舍入行为与 ROUND_UP 相同;
     * 如果为负，则舍入行为与 ROUND_DOWN 相同。
     * 注意，此舍入模式始终不会减少计算值。
     * 4、ROUND_FLOOR
     * 接近负无穷大的舍入模式。
     * 如果 BigDecimal 为正，则舍入行为与 ROUND_DOWN 相同;
     * 如果为负，则舍入行为与 ROUND_UP 相同。
     * 注意，此舍入模式始终不会增加计算值。
     * 5、ROUND_HALF_UP
     * 向“最接近的”数字舍入，如果与两个相邻数字的距离相等，则为向上舍入的舍入模式。
     * 如果舍弃部分 >= 0.5，则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
     * 注意，这是我们大多数人在小学时就学过的舍入模式(四舍五入)。
     * 6、ROUND_HALF_DOWN
     * 向“最接近的”数字舍入，如果与两个相邻数字的距离相等，则为上舍入的舍入模式。
     * 如果舍弃部分 > 0.5，则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
     * 7、ROUND_HALF_EVEN
     * 向“最接近的”数字舍入，如果与两个相邻数字的距离相等，则向相邻的偶数舍入。
     * 如果舍弃部分左边的数字为奇数，则舍入行为与 ROUND_HALF_UP 相同;
     * 如果为偶数，则舍入行为与 ROUND_HALF_DOWN 相同。
     * 注意，在重复进行一系列计算时，此舍入模式可以将累加错误减到最小。
     * 此舍入模式也称为“银行家舍入法”，主要在美国使用。四舍六入，五分两种情况。
     * 如果前一位为奇数，则入位，否则舍去。
     * 以下例子为保留小数点1位，那么这种舍入方式下的结果。
     * 1.15>1.2 1.25>1.2
     * 8、ROUND_UNNECESSARY
     * 断言请求的操作具有精确的结果，因此不需要舍入。
     * 如果对获得精确结果的操作指定此舍入模式，则抛出ArithmeticException。
     *
     * @return
     */
    public static String onKeep2Decimal(String number) {
        if (TextUtils.isEmpty(number)) {
            return "0";
        }
        BigDecimal bigDecimal = new BigDecimal(number);
        BigDecimal result = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);
        return result.toPlainString();
    }

    public static String onKeep3Decimal(String number) {
        if (TextUtils.isEmpty(number)) {
            return "0";
        }
        BigDecimal bigDecimal = new BigDecimal(number);
        BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP);
        return result.stripTrailingZeros().toPlainString();
    }
    public static String onKeep3Decimal_divide(String number) {
        if (TextUtils.isEmpty(number)) {
            return "0";
        }
        BigDecimal bigDecimal = new BigDecimal(number);
        BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP);
//        BigDecimal result1=  result.divide(new BigDecimal("1000"));
        return result.divide(new BigDecimal("1000")).setScale(3, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
    }
    public static String onKeep5Decimal_divide(String number) {
        if (TextUtils.isEmpty(number)) {
            return "0";
        }
        BigDecimal bigDecimal = new BigDecimal(number);
        BigDecimal result = bigDecimal.setScale(5, BigDecimal.ROUND_HALF_UP);
//        BigDecimal result1=  result.divide(new BigDecimal("1000"));
        return result.divide(new BigDecimal("1000")).setScale(5, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
    }

    public static String onKeep2Decimal_new(String number) {
        if (TextUtils.isEmpty(number)) {
            return "0";
        }
        BigDecimal bigDecimal = new BigDecimal(number);
        BigDecimal result = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);
        return result.stripTrailingZeros().toPlainString();
    }


    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 2;

    /**
     * 加法
     *
     * @param num
     * @param num1
     * @return
     */
    public static BigDecimal add(BigDecimal num, BigDecimal num1) {
        return num.add(num1);
    }

    /**
     * 提供精确的加法运算(默认四舍五入，根据scale保留小数位数)
     *
     * @param num
     * @param num1
     * @param scale
     * @return
     */
    public static BigDecimal add(BigDecimal num, BigDecimal num1, int scale) {
        return num.add(num1).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 提供精确的加法运算(默认四舍五入，根据scale保留小数位数)
     *
     * @param add
     * @param add1
     * @param scale
     * @return
     */
    public static BigDecimal add(String add, String add1, int scale) {
        BigDecimal num = new BigDecimal(add);
        BigDecimal num1 = new BigDecimal(add1);
        return num.add(num1).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 减法
     *
     * @param num
     * @param num1
     * @return
     */
    public static BigDecimal sub(BigDecimal num, BigDecimal num1) {
        return num.subtract(num1);
    }

    /**
     * 提供精确的减法运算(默认四舍五入，根据scale保留小数位数)
     *
     * @param num
     * @param num1
     * @param scale
     * @return
     */
    public static BigDecimal sub(BigDecimal num, BigDecimal num1, int scale) {
        return num.subtract(num1).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 提供精确的减法运算(默认四舍五入，根据scale保留小数位数)
     *
     * @param minus
     * @param minus1
     * @return
     */
    public static BigDecimal sub(String minus, String minus1, int scale) {
        BigDecimal num = new BigDecimal(minus);
        BigDecimal num1 = new BigDecimal(minus1);
        return sub(num, num1, scale);
    }

    /**
     * 乘法
     *
     * @param num
     * @param num1
     * @return
     */
    public static BigDecimal multiply(BigDecimal num, BigDecimal num1) {
        return num.multiply(num1);
    }

    /**
     * 提供精确的乘法运算(默认四舍五入,保留小数位数根据scale决定)
     *
     * @param num
     * @param num1
     * @param scale
     * @return
     */
    public static BigDecimal multiply(String num, String num1, int scale) {
        BigDecimal mul = new BigDecimal(num);
        BigDecimal mul1 = new BigDecimal(num1);
        return multiply(mul, mul1, scale);
    }

    /**
     * 提供精确的乘法运算(默认四舍五入，保留小数位数根据scale确定)
     *
     * @param num
     * @param num1
     * @param scale
     * @return
     */
    public static BigDecimal multiply(BigDecimal num, BigDecimal num1, int scale) {
        return num.multiply(num1).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 除法(除法除不尽会抛异常)
     *
     * @param num
     * @param num1
     * @return
     */
    public static BigDecimal divide(BigDecimal num, BigDecimal num1) {
        return num.divide(num1, DEF_DIV_SCALE);
    }

    /**
     * 提供精确的除法运算(默认四舍五入保留两位小数)
     *
     * @param dividend
     * @param divisor
     * @return
     */
    public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor, int scale) {
        return dividend.divide(divisor, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 提供精确的除法运算(默认四舍五入，保留小数位数根据scale决定)
     *
     * @param dividend
     * @param divisor
     * @param scale
     * @return
     */
    public static BigDecimal divide(String dividend, String divisor, int scale) {
        BigDecimal num = new BigDecimal(dividend);
        BigDecimal num1 = new BigDecimal(divisor);
        return divide(num, num1, scale);
    }

    /**
     * 提供精确的取余数运算(小数保留位数根据scale决定)
     *
     * @param dividend
     * @param divisor
     * @param scale
     * @return
     */
    public static BigDecimal balance(BigDecimal dividend, BigDecimal divisor, int scale) {
        return dividend.remainder(divisor).setScale(scale);
    }

    /**
     * 提供精确的取余数运算(默认保留两位小数)
     *
     * @param dividend
     * @param divisor
     * @return
     */
    public static BigDecimal balance(BigDecimal dividend, BigDecimal divisor) {
        return dividend.remainder(divisor).setScale(DEF_DIV_SCALE);
    }

    /**
     * 比较BigDecimal,相等返回0,num>num1返回1,num<num1返回-1
     *
     * @param num
     * @param num1
     * @return
     */
    public static int compareTo(BigDecimal num, BigDecimal num1) {
        return num.compareTo(num1);
    }

    public static String formatScaleNum(String num) {
        if (TextUtils.isEmpty(num)) {
            return "";
        }
        BigDecimal decimal = new BigDecimal(num);
        BigDecimal setScale = decimal.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_HALF_DOWN);
        return setScale.toPlainString();
    }

    public static void main(String[] args) {
        BigDecimal divide = divide("12", "11", 2);
        System.out.println(divide.doubleValue());

        BigDecimal num1 = new BigDecimal("121");
        BigDecimal num2 = new BigDecimal("122");
        System.out.println(compareTo(num1, num2));

    }

}
